package com.bsg.upm.service;


import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.cache.DefinitionMetricClassCache;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.dao.DefinitionMetricClassDao;
import com.bsg.upm.entity.DefinitionMetricClassEntity;
import com.bsg.upm.entity.DefinitionMetricEntity;
import com.bsg.upm.entity.SubServEntity;
import com.bsg.upm.entity.UnitEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
 
@Service
public class MonitorSubServConfigService extends BaseService {
	

	@Resource
	private DefinitionMetricClassCache definitionMetricClassCache;
	
	@Resource
	private DefinitionMetricClassDao definitionMetricClassDao;
	
	@Resource
	private MonitorHostConfigService monitorHostConfigService;
	
	@Resource
	private MonitorContainerConfigService monitorContainerConfigService;
	
	public RespJson listEvent(String subservId) throws APIException {
		JSONArray retJsonArray = new JSONArray();
				
		JSONArray containers = monitorContainerConfigService.listContainersEvent(subservId);
		retJsonArray.addAll(containers);
		
		JSONArray units = listUnitEvent(subservId);
		retJsonArray.addAll(units);
		
		return RespJsonFactory.buildOK(retJsonArray);
		
	}
	
	public RespJson listMetricClass(String subservId) throws APIException {
		JSONArray retJsonArray = new JSONArray();
				
		JSONArray containers = monitorContainerConfigService.listContainersMetricClass(subservId);
		retJsonArray.addAll(containers);
	
		JSONArray units = listUnitMetricClass(subservId);
		retJsonArray.addAll(units);
		
		return RespJsonFactory.buildOK(retJsonArray);
		
		
	}
	
	
	
	public JSONArray listUnitMetricClass(String subservId) throws APIException {
		JSONArray retJsonArray = new JSONArray();

		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return retJsonArray;
		}

		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);
		if (units.isEmpty()) {
			return retJsonArray;
		}

		JSONArray metricConfigs = getUnitMetricClassFromHS(siteId, (String) units.get(0));
		List<DefinitionMetricClassEntity> dfMetrics = definitionMetricClassCache.listDfMetricClassFromCache();

		for (Object config : metricConfigs) {
			retJsonArray.add(monitorHostConfigService.getMetricClassShowObject(dfMetrics, (JSONObject) config));
		}

		return retJsonArray;
	}
	
	
	public JSONArray listUnitEvent(String subservId) throws APIException {
		JSONArray retJsonArray = new JSONArray();

		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return retJsonArray;
		}

		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getRelateIdBySubServId(subservId);
		if (containers.isEmpty()) {
			return retJsonArray;
		}

		JSONArray eventConfigs = getUnitEventFromHS(siteId, (String) containers.get(0));

		List<DefinitionMetricEntity> dfMetrics = definitionMetricCache.listDfMetricFromCache();
		for (Object config : eventConfigs) {
			retJsonArray.add(monitorHostConfigService.getEventShowObj(dfMetrics, (JSONObject) config));
		}


		return retJsonArray;
	}
	
	public RespJson enableMetricClassBySubServ(String subservId, String metricClass) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);

		String urlPattern = "/{0}/units/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:enableMetricClassBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	public RespJson disableMetricClassBySubServ(String subservId, String metricClass) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);

		String urlPattern = "/{0}/units/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:diableMetricClassBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	public RespJson enableEventBySubServ(String subservId, String metric,String metricType) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(metricType, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);

		String urlPattern = "/{0}/units/event/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:enablecEventBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	public RespJson disableEventBySubServ(String subservId, String metric,String metricType) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(metricType, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);

		String urlPattern = "/{0}/units/event/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:disablecEventBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	public RespJson disableEventLevelBySubServ(String subservId, String metric, String level,String metricType) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(metricType, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);
		paramJson.put("level", level);

		String urlPattern = "/{0}/units/level/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:disableEventLevelBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	public RespJson eableEventLevelBySubServ(String subservId, String metric, String level,String metricType) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(metricType, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);
		paramJson.put("level", level);

		String urlPattern = "/{0}/units/level/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:eableEventLevelBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	public RespJson updateEventLevelBySubServ(String subservId, String metric, String level, String start, String end,String metricType) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray units = getRelateIdBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(metricType, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", units);
		paramJson.put("level", level);
		paramJson.put("start", start);
		paramJson.put("end", end);
		
		String urlPattern = "/{0}/units/level/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorSubServConfigService:updateEventLevelBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}
	
	
	
	private JSONArray getUnitMetricClassFromHS(String siteId, String unitId) throws APIException {

		String urlPattern = "/{0}/metricclass/{1}?metric_object_type=unit";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, unitId);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("getUnitMetricClassFromHS fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		JSONObject datas = (JSONObject) httpRespJson.getData();
		if (datas.isEmpty()) {
			return new JSONArray();
		}

		return datas.getJSONArray("metric_configs");

	}
	
	private JSONArray getUnitEventFromHS(String siteId, String unitId) throws APIException {

		String urlPattern = "/{0}/event/{1}?metric_object_type=unit";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, unitId);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("getContainersEventFromHS fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		JSONObject datas = (JSONObject) httpRespJson.getData();
		if (datas.isEmpty()) {
			return new JSONArray();
		}

		return datas.getJSONArray("event_configs");

	}
	 
	private boolean isHttp2XX(int status) {
		if (status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED) {
			return true;
		}
		return false;
	}

	private JSONArray getRelateIdBySubServId(String id) {
		JSONArray ret = new JSONArray();

		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("subServId", id);
		List<UnitEntity> unitEntities = unitDao.list(paramMap);
		for (UnitEntity unitEntity : unitEntities) {
			ret.add(unitEntity.getRelateId());
		}

		return ret;
	}
 
}